package com.ww.springboot.boot.javabase.queue;

import com.google.common.collect.Queues;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * 描述：
 *
 * @author 🧑 ‍wanwei
 * @since 2024-08-13 09:37
 */
public class BlockingQueueDemo {

    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3, true);

        offer(blockingQueue);
        offer2(blockingQueue);

        add(blockingQueue);

        poll(blockingQueue);

        put(blockingQueue);

        drainTo(blockingQueue);

        drainTo2(blockingQueue);

        drainUtil(blockingQueue);
    }

    private static void drainUtil(BlockingQueue<String> blockingQueue) throws InterruptedException {
        offer(blockingQueue);
        List<String> list3 = new ArrayList<>();
        //指定数量或者指定时间 某一个满足就返回
        Queues.drain(blockingQueue, list3, 200, 100, TimeUnit.MILLISECONDS);
        Queues.drain(blockingQueue, list3, 200, Duration.ofSeconds(1) );
    }

    private static void offer(BlockingQueue<String> blockingQueue) {
        for (int i = 0; i < 10; i++) {
            //往头部插入一条数据 返回是否成功
            boolean offer = blockingQueue.offer("" + i);
            System.out.println(i + " " + offer);
        }
    }

    private static void offer2(BlockingQueue<String> blockingQueue) throws InterruptedException {
        for (int i = 0; i < 3; i++) {
            //往头部插入一条数据 允许等待指定时间  返回是否成功
            boolean offer = blockingQueue.offer("" + i, 1, TimeUnit.SECONDS);
            System.out.println(i + " " + offer + System.currentTimeMillis());
        }
    }

    private static void add(BlockingQueue<String> blockingQueue) {
        for (int i = 0; i < 10; i++) {
            //往头部插入一条数据 返回是否成功 如果满了 会直接抛异常
            boolean offer = blockingQueue.add("" + i);
            System.out.println(i + " " + offer);
        }
    }

    private static void poll(BlockingQueue<String> blockingQueue) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            //从头部取一条数据 如果队列为空 允许等待指定时间再返回
            String poll = blockingQueue.poll(1, TimeUnit.SECONDS);
            System.out.println(poll);
        }
    }

    private static void put(BlockingQueue<String> blockingQueue) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            //往队列中插入元素 如果已满 则一直等待
            blockingQueue.put("" + i);
        }
    }

    private static void drainTo(BlockingQueue<String> blockingQueue) {
        offer(blockingQueue);

        List<String> list = new ArrayList<>();
        //将所有数据取出到list中
        int n = blockingQueue.drainTo(list);
        System.out.println(n);
        System.out.println(list.toString());
    }

    private static void drainTo2(BlockingQueue<String> blockingQueue) {
        offer(blockingQueue);

        List<String> list2 = new ArrayList<>();
        //将所有数据取出到list中
        int m = blockingQueue.drainTo(list2, 2);
        System.out.println(m);
        System.out.println(list2);
    }
}
